package cn.com.w.word.filter.service.impl;

import cn.com.w.word.filter.service.WordFilterService;
import com.google.common.base.Charsets;
import com.google.common.hash.BloomFilter;
import com.google.common.hash.Funnel;
import com.google.common.hash.PrimitiveSink;
import com.hankcs.hanlp.seg.Dijkstra.DijkstraSegment;
import com.hankcs.hanlp.seg.Segment;
import com.hankcs.hanlp.seg.common.Term;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;


/**
 * 敏感词过滤服务实现
 *
 * @author zhangxiaolong
 * @date 2022/7/18 21:15
 * @description
 * @menu tool-temp
 **/
@Service
@Slf4j
public class WordFilterServiceImpl implements WordFilterService {

    private static BloomFilter<String> configuredFilter;

    private static final BloomFilter<String> filter = BloomFilter.create(new Funnel<String>() {
        private static final long serialVersionUID = 1L;

        @Override
        public void funnel(String arg0, PrimitiveSink arg1) {
            arg1.putString(arg0, Charsets.UTF_8);
        }
    }, 1024 * 1024 * 32);

    /**
     * 读取带敏感词的布隆过滤器
     *
     * @return
     * @throws IOException
     */
    public BloomFilter<String> getSensitiveWordsFilter() throws IOException {
        InputStreamReader read = null;
        BufferedReader bufferedReader = null;
        read = new InputStreamReader(this.getClass().getClassLoader().getResourceAsStream("keyword/keyword.dic"), StandardCharsets.UTF_8);
        bufferedReader = new BufferedReader(read);
        for (String txt = null; (txt = bufferedReader.readLine()) != null; ) {
            filter.put(txt);
        }
        this.configuredFilter = filter;
        return filter;
    }

    /**
     * 获取文档中存在的敏感词
     *
     * @param segment
     * @return
     */
    @Override
    public List<String> segmentSensitiveFilter(String segment) {
        if (configuredFilter == null) {
            try {
                getSensitiveWordsFilter();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        List<String> result = new ArrayList<>();
        Segment shortestSegment = new DijkstraSegment().enableCustomDictionary(true)
                .enablePlaceRecognize(true)
                .enableOrganizationRecognize(true)
                .enableNameRecognize(true)
                .enableAllNamedEntityRecognize(true).enableMultithreading(true)
                .enableCustomDictionary(true);
        List<Term> termList = shortestSegment.seg(segment);

        for (Term term : termList) {
            // 如果布隆过滤器中找到了对应的词，则认为敏感检测不通过
            if (configuredFilter.mightContain(term.word)) {
                log.info("检测到敏感词：" + term.word);
                result.add(term.word);
            }
        }
        return result;
    }

    public static void main(String[] args) {
        WordFilterServiceImpl bloomFilterServiceImpl = new WordFilterServiceImpl();
        bloomFilterServiceImpl.segmentSensitiveFilter("沙发敦敦实实阴茎挺进滋润肉洞里在阴户中抽送TMD为而乏味sagsrgqwer奸你dfaherqgaev啊多发发吧的阴茎阴茎");
        System.out.println("ok");
    }
}
